package util

import (
	"fmt"
	"net/http"

	"illuminant/config"
	"illuminant/logger"

	apiclient "gitee.com/wangyubin/gutils/api_client"
	jsoniter "github.com/json-iterator/go"
)

func Graphql(query string, params map[string]interface{}, respData interface{}) error {
	lg := logger.GetLogger()
	cnf := config.Get()

	data, err := PostJson(cnf.Graphql.Endpoint, map[string]interface{}{
		"query":     query,
		"variables": params,
	})
	if err != nil {
		lg.Err(err).Msg("GRAPHQL: graphql request")
		return err
	}

	var resp struct {
		Data   interface{} `json:"data"`
		Errors []struct {
			Message string `json:"message"`
		} `json:"errors"`
	}

	// 这里的Data 是类型不定的
	resp.Data = respData
	err = jsoniter.Unmarshal(data, &resp)
	if err != nil {
		lg.Err(err).Msg("GRAPHQL: parse request")
		return err
	}

	if resp.Errors != nil {
		lg.Warn().Str("error", resp.Errors[0].Message).Msg("GRAPHQL: -> request error")
		return fmt.Errorf("%s\n", resp.Errors[0].Message)
	}

	return nil
}

func GetJson(url string, jsonReq interface{}) ([]byte, error) {

	var err error
	var reqBody []byte
	conf := config.Get()

	c := apiclient.NewClient(url)
	if reqBody, err = jsoniter.Marshal(jsonReq); err != nil {
		return nil, err
	}
	c.Headers["Content-Type"] = "application/json"
	c.Headers["x-hasura-admin-secret"] = conf.Graphql.Secret
	c.RequestData = reqBody
	if err = c.Get(); err != nil {
		return nil, err
	}

	if c.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("http status code: %d", c.StatusCode)
	}
	return c.ResponseData, err
}

func PostJson(url string, jsonReq interface{}) ([]byte, error) {

	var err error
	var reqBody []byte
	conf := config.Get()

	c := apiclient.NewClient(url)
	if reqBody, err = jsoniter.Marshal(jsonReq); err != nil {
		return nil, err
	}
	c.Headers["Content-Type"] = "application/json"
	c.Headers["x-hasura-admin-secret"] = conf.Graphql.Secret
	c.RequestData = reqBody
	if err = c.Post(); err != nil {
		return nil, err
	}

	if c.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("http status code: %d", c.StatusCode)
	}
	return c.ResponseData, err
}
